home *** CD-ROM | disk | FTP | other *** search
/ Languguage OS 2 / Languguage OS II Version 10-94 (Knowledge Media)(1994).ISO / gnu / mtools.lha / mtools-2.0.7 / mrd.c < prev    next >
C/C++ Source or Header  |  1992-09-10  |  5KB  |  202 lines

  1. /*
  2.  * Delete an MSDOS subdirectory
  3.  *
  4.  * Emmet P. Gray            US Army, HQ III Corps & Fort Hood
  5.  * ...!uunet!uiucuxc!fthood!egray    Attn: AFZF-DE-ENV
  6.  * fthood!egray@uxc.cso.uiuc.edu    Directorate of Engineering & Housing
  7.  *                     Environmental Management Office
  8.  *                     Fort Hood, TX 76544-5057
  9.  */
  10.  
  11. #include <stdio.h>
  12. #include <signal.h>
  13. #include "msdos.h"
  14. #include "patchlevel.h"
  15.  
  16. int fd = -1;                /* the file descriptor for the device */
  17. int dir_start;                /* starting sector for directory */
  18. int dir_len;                /* length of directory (in sectors) */
  19. int dir_entries;            /* number of directory entries */
  20. int clus_size;                /* cluster size (in sectors) */
  21. char *mcwd;                /* the Current Working Directory */
  22. int fat_error;                /* FAT error detected? */
  23.  
  24. static int got_signal(), is_empty();
  25.  
  26. main(argc, argv)
  27. int argc;
  28. char *argv[];
  29. {
  30.     int i, ismatch, entry, oops, empty, got_one, missed_one;
  31.     unsigned int start;
  32.     char *filename, *newfile, *get_name(), drive, *pathname, *get_path();
  33.     char *unix_name(), get_drive(), last_drive, *fix_mcwd();
  34.     void exit(), fat_write(), dir_write(), disk_flush(), dir_flush();
  35.     struct directory *dir, *dir_read();
  36.                     /* catch signals */
  37.     signal(SIGINT, (SIG_TYPE(*) ()) got_signal);
  38.     signal(SIGTERM, (SIG_TYPE(*) ()) got_signal);
  39.     signal(SIGQUIT, (SIG_TYPE(*) ()) got_signal);
  40.  
  41.     if (argc == 1) {
  42.         fprintf(stderr, "Mtools version %s, dated %s\n", VERSION, DATE);
  43.         fprintf(stderr, "Usage: %s mdsosdirectory [msdosdirectories...]\n", argv[0]);
  44.         exit(1);
  45.     }
  46.  
  47.     got_one = 0;
  48.     missed_one = 0;
  49.     last_drive = 'x';
  50.     mcwd = fix_mcwd();
  51.  
  52.     for (i = 1; i < argc; i++) {
  53.         drive = get_drive(argv[i]);
  54.         if (drive != last_drive) {
  55.             if (last_drive != 'x') {
  56.                 fat_write();
  57.                 dir_flush();
  58.                 disk_flush();
  59.             }
  60.  
  61.             if (init(drive, 2)) {
  62.                 fprintf(stderr, "%s: Cannot initialize '%c:'\n", argv[0], drive);
  63.                 missed_one++;
  64.                 continue;
  65.             }
  66.             last_drive = drive;
  67.         }
  68.  
  69.         filename = get_name(argv[i]);
  70.         pathname = get_path(argv[i]);
  71.         if (subdir(drive, pathname)) {
  72.             missed_one++;
  73.             continue;
  74.         }
  75.  
  76.         oops = 0;
  77.         ismatch = 0;
  78.         for (entry = 0; entry < dir_entries; entry++) {
  79.             dir = dir_read(entry);
  80.                     /* if empty */
  81.             if (dir->name[0] == 0x0)
  82.                 break;
  83.                     /* if erased */
  84.             if (dir->name[0] == 0xe5)
  85.                 continue;
  86.                     /* if not dir */
  87.             if (!(dir->attr & 0x10))
  88.                 continue;
  89.  
  90.             newfile = unix_name(dir->name, dir->ext);
  91.             if (match(newfile, filename)) {
  92.                 start = dir->start[1] * 0x100 + dir->start[0];
  93.                 if ((empty = is_empty(start)) < 0)
  94.                     break;
  95.                 if (!empty) {
  96.                     fprintf(stderr, "%s: Directory \"%s\" is not empty\n", argv[0], filename);
  97.                     oops++;
  98.                     break;
  99.                 }
  100.                 if (!start) {
  101.                     fprintf(stderr, "%s: Can't remove root directory\n", argv[0]);
  102.                     oops++;
  103.                     break;
  104.                 }
  105.                 if (fat_free(start))
  106.                     break;
  107.                 dir->name[0] = 0xe5;
  108.                 dir_write(entry, dir);
  109.                 ismatch = 1;
  110.                 got_one++;
  111.             }
  112.         }
  113.         if (fat_error) {
  114.             missed_one++;
  115.             break;
  116.         }
  117.  
  118.         if (oops) {
  119.             missed_one++;
  120.             continue;
  121.         }
  122.  
  123.         if (!ismatch) {
  124.             fprintf(stderr, "%s: Directory \"%s\" not found\n", argv[0], filename);
  125.             missed_one++;
  126.         }
  127.     }
  128.                     /* write the FAT, flush the buffers */
  129.     fat_write();
  130.     dir_flush();
  131.     disk_flush();
  132.     close(fd);
  133.     if (got_one && missed_one)
  134.         exit(2);
  135.     if (missed_one)
  136.         exit(1);
  137.     exit(0);
  138. }
  139.  
  140. /*
  141.  * See if directory is empty.  Returns 1 if empty, 0 if not, and -1 on error.
  142.  * Can't use subdir() and dir_read() as it would clobber the globals.
  143.  */
  144.  
  145. static int
  146. is_empty(fat)
  147. unsigned int fat;
  148. {
  149.     register int i;
  150.     int next, buflen;
  151.     long sector;
  152.     extern unsigned int last_fat, fat_decode();
  153.     unsigned char tbuf[MAX_CLUSTER];
  154.     void disk_read();
  155.  
  156.     /* CONSTCOND */
  157.     while (1) {
  158.         sector = (long) (fat - 2) * clus_size + dir_start + dir_len;
  159.         buflen = clus_size * MSECTOR_SIZE;
  160.         disk_read(sector, tbuf, buflen);
  161.  
  162.                     /* check first character of name */
  163.         for (i = 0; i < MSECTOR_SIZE; i += MDIR_SIZE) {
  164.             if (tbuf[i] == '.')
  165.                 continue;
  166.             if (tbuf[i] != 0x0 && tbuf[i] != 0xe5)
  167.                 return(0);
  168.         }
  169.                     /* get next cluster number */
  170.         next = fat_decode(fat);
  171.         if (next == 1) {
  172.             fprintf(stderr, "is_empty: FAT problem\n");
  173.             return(-1);
  174.         }
  175.                     /* end of cluster chain */
  176.         if (next >= last_fat)
  177.             break;
  178.         fat = next;
  179.     }
  180.     return(1);
  181. }
  182.  
  183. /*
  184.  * Do a graceful exit if the program is interrupted.  This will reduce
  185.  * (but not eliminate) the risk of generating a corrupted disk on
  186.  * a user abort.
  187.  */
  188.  
  189. static int
  190. got_signal()
  191. {
  192.     void exit(), disk_flush(), fat_write(), dir_flush();
  193.  
  194.     if (fd < 0)
  195.         exit(1);
  196.     fat_write();
  197.     dir_flush();
  198.     disk_flush();
  199.     close(fd);
  200.     exit(1);
  201. }
  202.